<?php

/**
 * Class for sending mail.
 *
 * @author Ian Clarence <ian.clarence@gmail.com>
 */
class Mail {

    private $to = array();
    private $from = array();
    private $cc = array();
    private $bcc = array();
    private $returnPath = NULL;
    private $replyTo = NULL;
    private $isHtml;

    /**
     * The constructor.
     *
     * @param string $subject
     * @param string $message
     * @param bool $isHtml
     * @param EmailAddress $to
     * @param EmailAddress $from
     * @param EmailAddress $returnPath
     * @param EmailAddress $replyTo
     * @param string $mimeVersion
     */
    public function __construct(
        $subject = NULL,
        $message = NULL,
        $isHtml = TRUE,
        $to = NULL,
        $from = NULL,
        $returnPath = NULL,
        $replyTo = NULL,
        $mimeVersion = "1.0"
    ) {
        $this->subject = $subject;
        $this->message = $message;
        $this->to[0] = $to;
        $this->from[0] = $from;
        $this->returnPath = $returnPath;
        $this->replyTo = $replyTo;
        $this->mimeVersion = $mimeVersion;
        $this->contentType = "text/" . ($isHtml ? "html" : "plain") . "; charset=" . CHARSET;
        $this->xMailer = "PHP-" . phpversion();
    }

    /**
     * Adding an email address to the "to", "from", "cc" or "bcc" lists.
     *
     * @param string $task
     * @param EmailAddress $emailAddress
     */
    public function add($task, EmailAddress $emailAddress) {
        switch($task) {
            case "to":
                array_push($this->to, $emailAddress);
                break;
            case "from":
                array_push($this->from, $emailAddress);
                break;
            case "cc":
                array_push($this->cc, $emailAddress);
                break;
            case "bcc":
                array_push($this->bcc, $emailAddress);
                break;
        }
    }

    /**
     * Converting an array of email addresses to a comma delimited string.
     *
     * @param array $emailAddresses
     * @return string
     */
    private function emailListToString(array $emailAddresses) {
        $output = "";
        $numberOfEmailAddresses = count($emailAddresses);
        if ($numberOfEmailAddresses == 0) {
            return $output;
        }
        foreach ($emailAddresses as $emailAddressKey => $emailAddress) {
            if ($emailAddress instanceof EmailAddress) {
                $output .= $emailAddress->render();
                $output .= ($emailAddressKey + 1 < $numberOfEmailAddresses) ? "," : "";
            }
        }
        return $output;
    }

    /**
     * Returning the email headers.
     *
     * @return string
     */
    private function getHeaders() {
        $output = "MIME-Version: " . $this->mimeVersion . PHP_EOL;
        $output = "Content-Type: " . $this->contentType . PHP_EOL;
        if (count($this->from) > 0) {
            $output = "From: " . $this->emailListToString($this->from) . PHP_EOL;
        }
        if (count($this->cc) > 0) {
            $output = "Cc: " . $this->emailListToString($this->cc) . PHP_EOL;
        }
        if (count($this->bcc) > 0) {
            $output = "Bcc: " . $this->emailListToString($this->bcc) . PHP_EOL;
        }
        if ($this->replyTo != NULL) {
            $output = "Reply-To: " . $this->replyTo->render() . PHP_EOL;
        }
        if ($this->returnPath != NULL) {
            $output = "Return-Path: " . $this->returnPath->render() . PHP_EOL;
        }
        $output = "X-Mailer: " . $this->xMailer . PHP_EOL;
        return $output;
    }

    /**
     * Sending the email.
     * Returning a boolean: TRUE if the email was sent OK, FALSE otherwise.
     * @return bool
     */
    public function sendMail() {
        return mail(
            $this->emailListToString($this->to),
            $this->subject,
            $this->message,
            $this->getHeaders()
        );
    }

}